Skip to content

Conversation

@doxxx
Copy link
Contributor

@doxxx doxxx commented Nov 3, 2025

This adds a read_reset_cause function that returns an enum value derived from the SYSCTL.RSTCAUSE register.

Based on the work by @charlesbmi in #4732.

Example usage code tested on-device:

match embassy_mspm0::read_reset_cause() {
    Ok(cause) => {
        use embassy_mspm0::ResetCause::*;
        let desc = match cause {
            NoReset => "No reset since last read.",
            PorHwFailure => "POR- violation, SHUTDNSTOREx or PMU trim parity fault.",
            PorExternalNrst => "NRST triggered POR (>1s hold).",
            PorSwTriggered => "Software triggered POR.",
            BorSupplyFailure => "BOR0- violation.",
            BorWakeFromShutdown => "SHUTDOWN mode exit.",
            BootrstNonPmuParityFault => "Non-PMU trim parity fault.",
            BootrstClockFault => "Fatal clock failure.",
            BootrstSwTriggered => "Software triggered BOOTRST.",
            BootrstExternalNrst => "NRST triggered BOOTRST (<1s hold).",
            BootWwdt0Violation => "WWDT0 violation.",
            SysrstBslExit => "BSL exit.",
            SysrstBslEntry => "BSL entry.",
            SysrstWwdt1Violation => "WWDT1 violation.",
            SysrstFlashEccError => "Flash uncorrectable ECC error.",
            SysrstCpuLockupViolation => "CPULOCK violation.",
            SysrstDebugTriggered => "Debug triggered SYSRST.",
            SysrstSwTriggered => "Software triggered SYSRST.",
            CpurstDebugTriggered => "Debug triggered CPURST.",
            CpurstSwTriggered => "Software triggered CPURST.",
        };
        uart_log!(logger, 256, "Reset cause: {}", desc);
    },
    Err(code) => {
        uart_log!(logger, 256, "Reset cause: Unknown ({})", code);
    }
}

@doxxx
Copy link
Contributor Author

doxxx commented Nov 3, 2025

I don't understand those ci/build failures. This builds just fine locally.

@doxxx
Copy link
Contributor Author

doxxx commented Nov 3, 2025

Ah, I see the problem. For some MSPM0 chips the WWDT0 reset cause is a different level, so the generated PAC enum is named differently: BOOTWWDT0 vs SYSWWDT0.

@felipebalbi
Copy link

Ah, I see the problem. For some MSPM0 chips the WWDT0 reset cause is a different level, so the generated PAC enum is named differently: BOOTWWDT0 vs SYSWWDT0.

Maybe better to patch the PAC in that case?

@doxxx
Copy link
Contributor Author

doxxx commented Nov 3, 2025

There's other funny stuff going on with the MSPM0L13xx PAC -- it has WWDT0 and WWDT1 reset causes but there's only one WWDT0 defined for e.g MSPM0L1306... And some of the PAC reset cause values don't line up with the MSPM0 tech reference either.

I'll investigate some more.

@doxxx
Copy link
Contributor Author

doxxx commented Nov 4, 2025

I couldn't think of a better way to do this. Even if I fixed the reset cause Id enum in the PAC, it still would have a different set of values for the G-series, which would make for a horrific cfg condition to get it right. I thought it would be simpler to hard-code the values according to the tech reference.

@i509VCB
Copy link
Member

i509VCB commented Nov 4, 2025

I couldn't think of a better way to do this. Even if I fixed the reset cause Id enum in the PAC, it still would have a different set of values for the G-series, which would make for a horrific cfg condition to get it right. I thought it would be simpler to hard-code the values according to the tech reference.

In this case if there are enough differences I would just define 2 enums and pick based on chip family with cfg.

@doxxx
Copy link
Contributor Author

doxxx commented Nov 4, 2025

In this case if there are enough differences I would just define 2 enums and pick based on chip family with cfg.

It's one extra enum variant for G-series chips. Everything else is the same as far as I can tell. I can use cfg to make that one enum variant only preset for G series.

Are you okay with using the hard-coded values instead of the PAC enum values?

@i509VCB
Copy link
Member

i509VCB commented Nov 4, 2025

In this case if there are enough differences I would just define 2 enums and pick based on chip family with cfg.

It's one extra enum variant for G-series chips. Everything else is the same as far as I can tell. I can use cfg to make that one enum variant only preset for G series.

Are you okay with using the hard-coded values instead of the PAC enum values?

Something like

PorHwFailure = pac::ResetCause::PorHwFailure

is fine for enum definitions. But I'm not sure we want to make it repr(u8)

@doxxx
Copy link
Contributor Author

doxxx commented Nov 4, 2025

In this case if there are enough differences I would just define 2 enums and pick based on chip family with cfg.

It's one extra enum variant for G-series chips. Everything else is the same as far as I can tell. I can use cfg to make that one enum variant only preset for G series.
Are you okay with using the hard-coded values instead of the PAC enum values?

Something like

PorHwFailure = pac::ResetCause::PorHwFailure

is fine for enum definitions. But I'm not sure we want to make it repr(u8)

Alternatively, we don't define values for ResetCause and just let the compiler generate values. It doesn't look like other enums maintain the underlying register value.

@i509VCB
Copy link
Member

i509VCB commented Nov 4, 2025

Alternatively, we don't define values for ResetCause and just let the compiler generate values. It doesn't look like other enums maintain the underlying register value.

That's fine and probably preferable (we don't guarantee ABI stability of values)

@doxxx
Copy link
Contributor Author

doxxx commented Nov 4, 2025

Spurious job failure?

@i509VCB
Copy link
Member

i509VCB commented Nov 4, 2025

Spurious job failure?

C1104 failed to build. Probably that missing Id field you mentioned?

@doxxx
Copy link
Contributor Author

doxxx commented Nov 5, 2025

Spurious job failure?

C1104 failed to build. Probably that missing Id field you mentioned?

Ah crap, yes. I need to figure out how to do a build against every variant to catch that.

@doxxx
Copy link
Contributor Author

doxxx commented Nov 5, 2025

This depends on mspm0-rs/mspm0-data#18 to add the missing PAC enum for the C-series but will still need further fixes since there are subtle differences in the PAC enum between series.

Copy link
Member

@i509VCB i509VCB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pending on mspm0-data merge.

@doxxx
Copy link
Contributor Author

doxxx commented Nov 7, 2025

Still have to edit this to make two of the variants optional on c110x.

///
/// If the reset cause is not recognized, an `Err` containing the raw value is returned.
#[must_use = "Reading reset cause will clear it"]
pub fn read_reset_cause() -> Result<ResetCause, u8> {
Copy link
Member

@i509VCB i509VCB Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last comment is relating to return value. We do exhaustively measure each value hardware can produce, so we could mark other values as unreachable.

unreachable_unchecked is technically valid but would cause undefined behavior when new chips are added and this code isn't updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather err (haha) on the side of caution and keep the Err return to avoid undefined behavior. A runtime panic is better than undefined behavior.

Copy link
Member

@i509VCB i509VCB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible can you squash the commits?

This adds a read_reset_cause function that returns an enum value derived from the SYSCTL.RSTCAUSE register.

Based on the work by @charlesbmi in embassy-rs#4732.
@i509VCB i509VCB added this pull request to the merge queue Nov 8, 2025
Merged via the queue into embassy-rs:main with commit e187f43 Nov 8, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants